package cn.itsource.org.service.impl;

import cn.itsource.basic.service.impl.BaseServiceImpl;
import cn.itsource.basic.util.PageList;
import cn.itsource.basic.util.TreeUtil;
import cn.itsource.org.domain.Department;
import cn.itsource.org.mapper.DepartmentMapper;
import cn.itsource.org.query.DepartmentQuery;
import cn.itsource.org.service.IDepartmentService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;

@Service
public class DepartmentServiceImpl
        extends BaseServiceImpl<Department, DepartmentQuery>
        implements IDepartmentService {

    @Autowired(required = false)
    private DepartmentMapper departmentMapper;

    @Override
    public PageList<Department> queryPage(DepartmentQuery query) {

        PageHelper.startPage(query.getPageIndex(), query.getPageSize());
        List<Department> list = departmentMapper.query(query);
        PageInfo<Department> info = new PageInfo<>(list);
        return new PageList<>(info.getTotal(), info.getList());
    }

    @Override
    public List<Department> getSuperDept() {
        return departmentMapper.getSuperDept();
    }

    @Override
    public List<Department> getParentList() {
        return TreeUtil.getTree(mapper.selectAll());
    }

    @Override
    @Transactional//事务
    public boolean save(Department dept) {
        Department current = find(dept.getId());
        if (current == null) {
            mapper.insert(dept);
            parentProcess(dept);
        } else {
            if (Arrays.asList(dept.getParentIds()).contains(dept.getId())) {
                throw new RuntimeException("不能选择包含自己的节点!");
            }
            parentProcess(dept);
            changeChilrenNode(current.getDirPath(), dept);
        }
        return mapper.updateByPrimaryKey(dept) > 0;
    }

    private void changeChilrenNode(String oldDirPath, Department dept) {
        Example example = new Example(Department.class);
        example.and().andLike("dirPath", "%/" + dept.getId() + "/%");
        List<Department> list = mapper.selectByExample(example);
        String oldId = oldDirPath + "/";
        String newId = dept.getDirPath() + "/";
        for (Department item : list) {
            item.setDirPath(item.getDirPath().replace(oldId, newId));
            mapper.updateByPrimaryKey(item);
        }
    }

    private void parentProcess(Department dept) {
        Long[] parentIds = dept.getParentIds();
        if (parentIds != null && parentIds.length > 0) {
            Long parentId = parentIds[parentIds.length - 1];
            dept.setParentId(parentId);
            StringJoiner joiner = new StringJoiner("/");
            for (Long id : parentIds) {
                joiner.add(id.toString());
            }
            joiner.add(dept.getId().toString());
            dept.setDirPath("/" + joiner.toString());
        } else {
            dept.setParentId(null);
            dept.setDirPath("/" + dept.getId());
        }
    }
}
